# SpringBoot 源码分析

作者:Ethan.Yang
博客:https://blog.ethanyang.cn (opens new window)


# 自动装配

# @SpringBootApplication

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
1
2
3
4
5
6
7
8
9

注解解析

  • @SpringBootConfiguration
    • 声明当前类是 Spring 配置类,本质上是 @Configuration 的特化。
  • @EnableAutoConfiguration
    • Spring Boot 自动装配的核心注解,负责启动自动装配逻辑。
  • @ComponentScan
    • 开启包扫描,默认扫描启动类所在包及子包下的组件:
      • @Component@Service@Controller@Repository
      • @Configuration 配置类
    • 可通过 excludeFilters 排除不需要扫描的类。

# @EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
1
2
3
4
5
6
7

核心作用

  • AutoConfigurationImportSelector 注入 Spring IOC 容器
  • 为后续自动装配提供入口,确定要导入的自动配置类

# AutoConfigurationImportSelector

关注 selectImports() 方法,它是 Spring Boot 自动装配的核心入口。

@Import(AutoConfigurationImportSelector) 触发
    ↓
调用 selectImports() 方法
    ↓
判断是否启用自动配置 isEnabled()
    ├─ 若关闭 → 返回空数组
    └─ 若开启 → 执行 getAutoConfigurationEntry()
            ↓
        解析 @EnableAutoConfiguration 注解参数
            └─ 处理 exclude、excludeName 等排除配置
            ↓
        加载候选自动配置类 getCandidateConfigurations()
            ├─ Spring Boot 2.x 及以前:读取 META-INF/spring.factories
            └─ Spring Boot 3.x:读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
            ↓
        去重 removeDuplicates()  // 避免重复注册
            ↓
        解析并校验排除项 getExclusions() & checkExcludedClasses()
            ↓
        应用 AutoConfigurationImportFilter
            └─ 根据 @ConditionalOnClass、@ConditionalOnBean 等条件过滤不满足的配置
            ↓
        发布 AutoConfigurationImportEvent(事件通知机制)
            ↓
        封装为 AutoConfigurationEntry 对象
            ↓
selectImports() 返回最终自动配置类全限定名数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

理解

  • selectImports() 只负责确定哪些配置类需要注册,真正的 Bean 实例化还没有发生。
  • 其中@Conditional系列注解, 也在此处进行过滤, 最终返回的是需要注册的所有配置
  • 这个数组的每一个类,最终都会在容器刷新阶段递归注册成 BeanDefinition。

Spring Boot 动态装配触发与注册流程

无论是通过 @Import(xxxImportSelector),还是通过 BeanDefinitionRegistryPostProcessor 注册 Bean,最终都依赖于 Spring IOC 容器刷新流程中的 invokeBeanFactoryPostProcessors(beanFactory)

refresh() 容器刷新阶段
    ↓
invokeBeanFactoryPostProcessors(beanFactory)  
    └─ 容器刷新入口,触发所有 BeanFactoryPostProcessor
    ↓
invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())  
    └─ 获取当前注册的 BeanFactoryPostProcessor 列表
    ↓
分类执行 BeanDefinitionRegistryPostProcessor(可注册新 BeanDefinition)与普通 BeanFactoryPostProcessor
    ↓
registryProcessors.forEach(postProcessor -> postProcessor.postProcessBeanFactory(beanFactory))  
    └─ 核心:ConfigurationClassPostProcessor 被调用,触发动态装配
    ↓
ConfigurationClassPostProcessor.postProcessBeanFactory(beanFactory)  
    └─ 解析 @Configuration 类、@Import 注解、@Bean 方法等
    ↓
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory)  
    └─ 遍历候选配置类,生成 ConfigurationClass 对象
    ↓
parser.parse(candidates)  
    └─ 扫描 @Configuration、@Component、@Import 等注解,递归解析
    ↓
deferredImportSelectorHandler.process()  
    └─ 处理 DeferredImportSelector(延迟导入模块),按分组顺序注册自动配置
    ↓
handler.processGroupImports()  
    └─ 遍历 DeferredImportSelector 分组,递归调用 processImports()processImports(
    configurationClass,
    asSourceClass(configurationClass, exclusionFilter),
    Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
    exclusionFilter,
    false
)  
    └─ 递归解析 @Import 的配置类,生成 ConfigurationClass
    ↓
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata())  
    └─ AutoConfigurationImportSelector 获取自动配置类全限定名
    ↓
asSourceClasses(importClassNames, exclusionFilter)  
    └─ 转换为 SourceClass 对象,便于递归解析
    ↓
递归 processImports() → 每个配置类生成 ConfigurationClass 对象
    ↓
ConfigurationClassBeanDefinitionReader.registerBeanDefinitions()  
    └─ 注册配置类及其 @Bean 方法对应的 BeanDefinition
    ↓
BeanDefinition 注册完成,等待容器刷新实例化
    ↓
finishBeanFactoryInitialization() → 实例化 Bean
    └─ Bean 被创建并注入依赖,自动装配完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

理解

  1. 触发点
    • invokeBeanFactoryPostProcessors() 是动态装配真正的入口
    • 核心处理器是 ConfigurationClassPostProcessor,负责扫描配置类和 @Import
  2. selectImports 的作用
    • 它只负责返回配置类全限定名,不涉及实例化
    • 递归注册 BeanDefinition 才是自动装配的核心
  3. 递归机制
    • processImports() 会递归处理 @Import 和 DeferredImportSelector
    • 确保所有自动配置类和依赖类都被注册到 IOC 容器
  4. BeanDefinition 注册 vs 实例化
    • 注册阶段:生成 BeanDefinition(配置类 + @Bean 方法)
    • 实例化阶段:refresh() → finishBeanFactoryInitialization() → 创建 Bean 实例
    • 只有实例化后,自动装配才真正生效
  5. 自动装配“自动”原因
    • spring.factories 或 imports 文件记录了大量 AutoConfiguration 类
    • ImportSelector 自动导入 → 递归注册 BeanDefinition → 容器刷新实例化 → 自动装配完成
    • 条件注解(@ConditionalOnClass、@ConditionalOnBean 等)确保只装配满足条件的 Bean

# 启动依赖

在理解了 自动装配 的机制后,启动依赖就很好理解了:

  • 启动依赖 = Starter
    • 本质上是一个 jar 包,封装了一组功能依赖和约定的配置。
    • 用户在项目中引入这个依赖,相当于告诉 Spring Boot:“我想使用这个功能模块。”
  • 自动装配 = 动作 / 机制
    • 自动装配负责 根据类路径、条件注解以及 SPI 配置,将 Starter 中声明的 Bean 自动注册到当前项目的 IOC 容器中。
    • 换句话说,Starter 提供“入口”,自动装配完成“装载和生效”
  • 类比理解:
    • Starter 就像一份工具箱,里面装着各种工具(依赖和配置)。
    • 自动装配 就像工厂里的机器人,根据工具箱里的工具,自动把它们装配到你的项目中去使用。

可以参考 笔者Starter 示例 (opens new window) 来实现自己的 Spring Boot Starter

# Actuator 监控

Spring Boot Actuator 提供生产级监控与管理功能,常用功能包括:

  • 健康检查(Health)
  • 应用指标(Metrics)
  • 应用信息(Info)
  • 日志管理(Loggers)
  • 环境信息(Env / ConfigProps)

# 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
1
2
3
4

# 配置示例

management:
  endpoints:
    web:
      exposure:
        include: health, info, metrics, beans
  endpoint:
    health:
      show-details: always
1
2
3
4
5
6
7
8
  • include:指定要暴露的 endpoints
  • show-details:显示完整健康信息

访问示例:

http://localhost:8080/actuator/health
http://localhost:8080/actuator/metrics
http://localhost:8080/actuator/beans
1
2
3

Actuator 本质上是依赖 Spring Boot 自动装配机制动态注册 Bean,使用时无需手动配置 Bean 即可生效。

大多数生产项目都有第三方监视工具, 如 Prometheus(监控) + Grafana(可视化工具), 后面会有专栏进行讲解。